package com.hns.can.base.service;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.hns.can.base.entity.SysCorpInfoEntity;
import com.hns.can.base.entity.SysUserEntity;
import com.hns.can.common.constants.GlobalConst;
import com.hns.can.common.domain.ReturnResult;
import com.hns.can.common.entity.BaseEntity;
import com.hns.can.common.formula.FillCodeDscValue;
import com.hns.can.common.service.SysCacheService;
import com.hns.frame.enumrate.MsgType;
import com.hns.frame.exception.BusinessException;
import com.hns.frame.service.CommonService;
import com.hns.frame.util.ReflectUtil;
import com.hns.tool.pub.DateTool;
import com.hns.tool.pub.PubUtil;
import com.hns.tool.pub.UtilConfig;
import com.hns.tool.pub.UtilString;
import com.hns.frame.enumrate.IsClosed;


/**
 * 公司信息设置服务层
 * @author:JeffXu
 * @email:835264047@qq.com
 * @version Revision 2.0.0
 */
@Service
public class SysCorpInfoService extends CommonService {

	private static final Logger logger = LoggerFactory.getLogger(SysCorpInfoService.class);

	
	@Autowired
    private SysCacheService sysCacheService;
    
    @Autowired
    private FillCodeDscValue codeDscValue;
	
	/**
	 * 公司信息设置 - 获取当前用户所属的公司信息
	 * @param corpId 公司id
	 * @return 公司实体
	 * @author:JeffXu
	 * @email:835264047@qq.com
	 */
	@Transactional
	public BaseEntity searchSysCorpInfoByCorpId(String corpId) {
		SysCorpInfoEntity corpInfo = this.commonEntityDao.find(corpId, SysCorpInfoEntity.class);
        
        List<BaseEntity> list = new ArrayList<BaseEntity>();
        
        list.add(corpInfo);
        
        //解析代码描述信息
        corpInfo.setCityName(corpInfo.getCityId());
        
        Map<String, String> map = new HashMap<String, String>();
        map.put("cityName", ReflectUtil.getFieldValue(corpInfo, "provinceId").toString());
        codeDscValue.fillCodeDscValue(list, map);
        
        return corpInfo;
	}

	/**
	 * 获取公司树
	 * @param corpId
	 * @return 公司实体list
	 * @author:JeffXu
	 * @email:835264047@qq.com
	 */
	@SuppressWarnings("unchecked")
    public List<SysCorpInfoEntity> getCorpTree(String corpId){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("corpId", corpId);
        List<SysCorpInfoEntity> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("sysCorpInfo.getCorpTree", map), SysCorpInfoEntity.class);
    	return list;
    }
	
	/**
	 * 获取企业信息的数据
	 * @param paramMap 参数map
	 * @return 企业信息list
	 * @author:JeffXu
	 * @email:835264047@qq.com
	 */
    @SuppressWarnings("unchecked")
    @Transactional
    public List<SysCorpInfoEntity> getSysCorpInfoList(Map<String, Object> paramMap) {
        List<SysCorpInfoEntity> list = PubUtil.convertListMapToObject(
            this.sqlMapDao.selectList("sysCorpInfo.getSysCorpInfoList", paramMap), SysCorpInfoEntity.class);
        return list;
    }
	
    /**
     * 新增一个企业信息
     * @param entity 企业信息
     * @param user 当前用户
     * @return 返回消息实体
     * @throws Exception 保存异常
     * @author:JeffXu
     * @email:835264047@qq.com
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_CORP, key="#user.getCorpId()")
    @Transactional
    public String saveSysCorpInfo(SysCorpInfoEntity entity, SysUserEntity user) throws Exception {
        //校验 企业编码
//        Integer count1 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpCd", entity);
//        if(count1 > 0){
//        	throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业编码已经存在！");
//        }
        //校验 企业名称
        Integer count2 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpName", entity);
        if(count2 > 0){
        	throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业名称已经存在！");
        }
        //校验 企业简称
        Integer count3 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpShrtnm", entity);
        if(count3 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业简称已经存在！");
        }
        //校验 企业英文缩写
        Integer count4 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpEngAb", entity);
        if(count4 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业英文缩写已经存在！");
        }
        String corpId = UtilString.getUUID();
        entity.setCorpId(corpId);
        entity.setCrtTime(new Date());
        entity.setCrtUser(user.getAcctName());
        entity.setUpdateTime(new Date());
        entity.setUpdateUser(user.getAcctName());
        entity.setIsClosed(IsClosed.ENABLE.getFlag());
        commonEntityDao.save(entity);
        updateCorpCache(entity);
        return corpId;
    }
    
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_CORP, key="#user.getCorpId()")
    private String updateCorpCache(SysCorpInfoEntity entity){
    	return entity.getCityName();
    }

    /**
     * 删除一个企业信息
     * @param corpId 企业信息
     * @param user 当前用户
     * @return 返回消息实体
     * @throws Exception 删除异常
     * @author:JeffXu
     * @email:835264047@qq.com
     */
//    @CacheEvict(value=GlobalConst.SYSTEM_CACHE_NAME, key="'"+GlobalConst.CACHE_KEY_SYS_CODE+"'")
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_CORP, key="#user.getCorpId()")
    @Transactional
    public ReturnResult delSysCorpInfo(String corpId, SysUserEntity user) throws Exception {
        // 后台校验
        // 1.如果存在下级企业，不能删除
        Integer count1 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkChildCorpCount", corpId);
        if(count1 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "该企业存在下级企业，不能删除！");
        }
        // 2.如果存在组织机构的话,不能删除
        Integer count2 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkChildOrganCount", corpId);
        if(count2 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "该企业已经绑定了组织机构，不能删除！");
        }
        //modidiy by qianjy 2015-05-08
        SysCorpInfoEntity entity = commonEntityDao.find(corpId, SysCorpInfoEntity.class);
        entity.setEnabledSt("0");
        entity.setIsClosed(IsClosed.DISABLE.getFlag());
        //删除时也要带上用户和时间
        entity.setUpdateTime(new Date());
        entity.setUpdateUser(user.getAcctName());
    	commonEntityDao.update(entity);
    	return new ReturnResult();
    }
    
    /**
     * 公司信息设置 - 更新当前用户所属的公司信息
     * @param corpInfo 公司信息
     * @param user 当前用户信息
     * @throws Exception 值对象拷贝异常
     * @author:JeffXu
     * @email:835264047@qq.com
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_CORP, key="#user.getCorpId()")
    @Transactional
    public void updateSysCorpInfo(SysCorpInfoEntity corpInfo, SysUserEntity user) throws Exception {
        SysCorpInfoEntity dbcorpInfo = this.commonEntityDao.find(corpInfo.getCorpId(), SysCorpInfoEntity.class);
        PubUtil.copyPropertiesInclude(corpInfo, dbcorpInfo, new String[]{"corpName","corpShrtnm","corpBusLic","taxRegisCerti",
            "legalRepre","corpType","scopeBusiness","regisCapital","provinceId","cityId","postalcode","corpEngAb","detailAdr"});
        dbcorpInfo.setUpdateTime(new Date());
        dbcorpInfo.setUpdateUser(user.getAcctName());
        this.commonEntityDao.update(dbcorpInfo);
    }

    /**
     * 更新公司信息
     * @param corpInfo 公司信息
     * @param user 当前用户
     * @return 返回消息实体
     * @throws Exception 更新异常
     * @author:JeffXu
     * @email:835264047@qq.com
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_CORP, key="#user.getCorpId()")
    @Transactional
	public void updateSysCorpInfo2(SysCorpInfoEntity corpInfo, SysUserEntity user) throws Exception {
    	SysCorpInfoEntity dbcorpInfo = this.commonEntityDao.find(corpInfo.getCorpId(), SysCorpInfoEntity.class);
        PubUtil.copyPropertiesInclude(corpInfo, dbcorpInfo, new String[]{"corpCd","corpName","corpShrtnm","corpEngAb","parentCorpId","enabledSt",
            "corpBusLic","taxRegisCerti","legalRepre","corpType","scopeBusiness","regisCapital","provinceId","cityId","postalcode","detailAdr","isClosed"});
        
        //校验 企业编码
//        if(!dbcorpInfo.getCorpCd().equals(corpInfo.getCorpCd())){
//            Integer count1 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpCd", dbcorpInfo);
//            if(count1 > 0){
//                throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业编码已经存在！");
//            }
//        }
        //校验 企业名称
        Integer count2 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpName", dbcorpInfo);
        if(count2 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业名称已经存在！");
        }
        //校验 企业简称
        Integer count3 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpShrtnm", dbcorpInfo);
        if(count3 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业简称已经存在！");
        }
        //校验 企业英文缩写
        Integer count4 = (Integer) sqlMapDao.selectOne("sysCorpInfo.checkCorpEngAb", dbcorpInfo);
        if(count4 > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "您输入的企业英文缩写已经存在！");
        }
        dbcorpInfo.setUpdateTime(new Date());
        dbcorpInfo.setUpdateUser(user.getAcctName());
        updateCorpCache(dbcorpInfo);
        this.commonEntityDao.update(dbcorpInfo);
	}

    /**
     * 校验编码相同
     * @param corpInfo
     * @return
     */
	public int getCorpByCode(SysCorpInfoEntity corpInfo) {
		int count = (Integer) sqlMapDao.selectOne("sysCorpInfo.getCorpByCode", corpInfo);
        return count;
	}
	
	 /**
     * 这里这里用的是MultipartFile[] myfiles参数,所以前台就要用<input type="file" name="myfiles"/>
     */
    public String fileUpload(
            @RequestParam MultipartFile[] logo, String corpId,String uploadPath,
            HttpServletRequest request, HttpServletResponse response) throws IOException {
        //如果用的是Tomcat服务器，则文件会上传到\\%TOMCAT_HOME%\\webapps\\YourWebProject\\upload\\文件夹中
        //这里实现文件上传操作用的是commons.io.FileUtils类,它会自动判断/upload是否存在,不存在会自动创建
//        String realPath = request.getSession().getServletContext().getRealPath("/") + uploadPath;
        String realPath = UtilConfig.getString("upload_file_base_path") + uploadPath;//自定义图片保存路径

        //上传文件的原名(即上传前的文件名字)
        String originalFilename = null;
        //保存的文件名
        String saveFileName = "";

        //设置响应给前台内容的数据格式
        response.setContentType("text/plain; charset=UTF-8");
        //设置响应给前台内容的PrintWriter对象
        PrintWriter out = response.getWriter();
        //上传文件的原名(即上传前的文件名字)
        //如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解
        //如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且要指定@RequestParam注解
        //上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件
        for (MultipartFile myfile : logo) {
            System.out.println(URLDecoder.decode(myfile.getOriginalFilename(), "UTF-8"));

            if (myfile.isEmpty()) {
                throw new BusinessException(MsgType.WARN.getFlag(), "请选择文件后上传");
            } else if(myfile.getSize() > 307200){
            	throw new BusinessException(MsgType.WARN.getFlag(), "请上传小于300KB的图片");
            } else {
                //originalFilename = URLDecoder.decode(myfile.getOriginalFilename(), "UTF-8");
                originalFilename = new String(myfile.getOriginalFilename().getBytes("ISO-8859-1"), "utf-8");
                String suffix = originalFilename.substring(originalFilename.indexOf(".")+1, originalFilename.length());
//                System.out.println("后缀:"+suffix);
                if(suffix.equals("jpg") || suffix.equals("png")){
                	saveFileName = new String(corpId.getBytes("ISO-8859-1"), "utf-8") + originalFilename.substring(originalFilename.lastIndexOf("."));;
                }else{
                	throw new BusinessException(MsgType.WARN.getFlag(), "请选择后缀为JPG、PNG的图片");
                }
                
                try {
                    //这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉
                    //此处也可以使用Spring提供的MultipartFile.transferTo(File dest)方法实现文件的上传
                    FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, saveFileName));
                } catch (IOException e) {
                    logger.error("文件[" + originalFilename + "]上传失败,堆栈轨迹如下", e);
                    out.print("1文件上传失败，请重试！！");
                    out.flush();
                    return null;
                }
            }
        }
        out.print("0" + uploadPath + "\\" + saveFileName);
        out.flush();
        
        return realPath+saveFileName;
    }
	
	/**
	 * 保存公司Logo
	 */
	@Transactional
	public String saveCorpLogo(String url,String carNameMode,SysUserEntity user,String corpId){
		SysCorpInfoEntity entity = null;
		if("1".equals(user.getIsAdminRole())){
			entity = this.commonEntityDao.find(corpId, SysCorpInfoEntity.class);
		}else{
			entity = this.commonEntityDao.find(user.getCorpId(), SysCorpInfoEntity.class);
		}
		entity.setLogoPath(url);
		entity.setCarNameMode(carNameMode);
		this.commonEntityDao.update(entity);
		String msg = "保存成功";
		return msg;
	}
	
	/**
	 * 读取公司logo
	 */
	
	public SysCorpInfoEntity loadCorpLogo(SysUserEntity user,String corpId){
		SysCorpInfoEntity entity = null;
		if(corpId == null){
			entity = this.commonEntityDao.find(user.getCorpId(), SysCorpInfoEntity.class);
		}else if("1".equals(user.getIsAdminRole())){
			entity = this.commonEntityDao.find(corpId, SysCorpInfoEntity.class);
		}else{
			entity = this.commonEntityDao.find(user.getCorpId(), SysCorpInfoEntity.class);
		}
		return entity;
	}
	
	
	
	
}
